﻿using DeHeng_Mes.Model;
using S7.Net;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using zjxj_repair.Bean;
using zjxj_repair.Dao;
using zjxj_repair.Table;
using zjxj_repair.Mapper;
using MappingTable = zjxj_repair.Mapper.MappingTable;
using zjxj_repair.Utils;
using zjxj_repair.Bean.Model;
using System.Net.Sockets;
using DeHeng_Mes.Model.Table;

namespace zjxj_repair.Service
{
    public class EnableServices
    {
        #region 成员实例
        EnableDao enableDao = new EnableDao();
        #endregion


        /// <summary>
        /// 当前工具是否处于可以使能的状态
        /// </summary>
        /// <returns></returns>
        public bool IsEnable(string toolName)
        {
            string status = enableDao.ToolIsEnable(toolName);

            if (!string.IsNullOrEmpty(status))
            {
                return status.Equals("1") ? true : false;
            }

            return false;
        }

        /// <summary>
        /// 存储完成信息
        /// </summary>
        /// <param name="vinCode"></param>
        /// <param name="backString"></param>
        /// <param name="dateTime"></param>
        public void SaveBackString(string vinCode, string backString, DateTime dateTime, string status, string model)
        {
            enableDao.SaveBackString(vinCode, backString, dateTime, status, model);
        }

        /// <summary>
        /// 查询CCD点位名称
        /// </summary>
        /// <param name="vinCode"></param>
        /// <returns></returns>
        public List<string> QueryCCDData(string vinCode)
        {
            return enableDao.QueryCCDData(vinCode);
        }

        /// <summary>
        /// 查询工艺点位名称
        /// </summary>
        /// <param name="vinCode"></param>
        /// <returns></returns>
        public List<string> QueryPointData(string vinCode)
        {
            List<string> pointNames = new List<string>();

            // 查询FDS返修数据
            pointNames.AddRange(enableDao.QueryFDSData(vinCode));

            // 查询拧紧返修数据
            pointNames.AddRange(enableDao.QueryTightenData(vinCode));

            // 查询拉铆返修数据
            pointNames.AddRange(enableDao.QueryRiveteData(vinCode));

            return pointNames;
        }

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="repairs"></param>
        public void UpdateToolConfig(List<RepairToolConfig> repairs)
        {
            foreach (var repair in repairs)
            {
                enableDao.UpdateToolConfig(repair);
            }
        }

        /// <summary>
        /// 加载配置数据
        /// </summary>
        /// <returns></returns>
        public List<RepairToolConfig> QueryToolConfig()
        {
            List<RepairToolConfig> repairToolConfigs = enableDao.QueryToolConfig();

            foreach (var item in repairToolConfigs)
            {
                ConfigModelBean configModelBean = new ConfigModelBean()
                {
                    ToolIp = item.ToolIp,
                    ToolName = item.ToolName,
                    ToolPort = item.ToolPort,
                };

                ConfigModelInit.ReadList.Add(configModelBean);

                Tools.ProduceLogText($"[初始化操作]-初始化工具名称[{item.ToolName}]，初始化工具IP[{item.ToolIp}]，初始化工具端口[{item.ToolPort}]");
            }

            return repairToolConfigs;
        }

        /// <summary>
        /// 调用使能
        /// </summary>
        /// <param name="vinCode"></param>
        /// <param name="toolName"></param>
        /// <param name="toolModel"></param>
        /// <param name="pointName"></param>
        /// <returns></returns>
        public async Task<MessageBean> Enable(string vinCode, string toolName, string toolModel, string pointName, Button enableButton)
        {
            string toolButtonName = MappingTable.GetToolButtonName(toolName);

            // 查看工具心跳
            ConfigModelBean? configModelBean = ConfigModelInit.ReadList.Where(x => x.ToolName.Equals(toolButtonName)).FirstOrDefault();

            if (configModelBean == null || !configModelBean.IsCollected)
            {
                return new MessageBean()
                {
                    IsOk = false,
                    Message = "未连接！"
                };
            }

            // 将当前工具标记为使用状态
            bool enableStatusIsUpdate = ToolEnable(toolName, "1");

            if (enableStatusIsUpdate)
            {
                // 调用对应的使能方法
                switch (toolName)
                {
                    case "拉铆1":
                        return await RiveteEnable(configModelBean, vinCode, pointName, enableButton, toolModel);
                    case "拉铆2":
                        return await RiveteEnable(configModelBean, vinCode, pointName, enableButton, toolModel);
                    case "抽芯拉铆1":
                        return await RiveteEnable(configModelBean, vinCode, pointName, enableButton, toolModel);
                    case "抽芯拉铆2":
                        return await RiveteEnable(configModelBean, vinCode, pointName, enableButton, toolModel);
                    case "拧紧1":
                        return await TightenEnable(configModelBean, toolModel, enableButton);
                    case "拧紧2":
                        return await TightenEnable(configModelBean, toolModel, enableButton);
                }
            }
            return new MessageBean()
            {
                IsOk = false,
                Message = "未知错误"
            };
        }

        /// <summary>
        /// 使能标记
        /// </summary>
        /// <param name="toolName"></param>
        /// <returns></returns>
        public bool ToolEnable(string toolName, string status)
        {
            return enableDao.ToolEnable(toolName, status);
        }

        #region 使能方法(私有)
        /// <summary>
        /// 拧紧使能
        /// </summary>
        /// <param name="configModelBean"></param>
        /// <returns></returns>
        /*private async Task<MessageBean> TightenEnable(ConfigModelBean configModelBean, string toolModel)
        {
            bool isSend = await Tools.SendToServer(configModelBean, $"00230018            {toolModel.PadLeft(3, '0')}\0", configModelBean.ToolName);

            if (isSend)
            {
                while (true)
                {
                    ConfigModelBean item = ConfigModelInit.ReadList.Where(x => x.ToolName.Equals(configModelBean.ToolName)).FirstOrDefault();

                    if (item.IsEnable)
                    {
                        return new MessageBean()
                        {
                            IsOk = true,
                            Message = "使能成功！"
                        };
                    }

                    await Task.Delay(10);
                }
            }

            return new MessageBean()
            {
                IsOk = false,
                Message = "使能失败"
            };
        }*/
        private async Task<MessageBean> TightenEnable(ConfigModelBean configModelBean, string toolModel, Button enableButton)
        {
            int toolId = toolModel.ToInt();

            string psetId = $"{toolId:D3}";

            string psetID = $"00230018            {psetId}\0";

            bool isSend = await Tools.SendToServer(configModelBean, psetID, configModelBean.ToolName);

            if (!isSend)
            {
                return new MessageBean { IsOk = false, Message = "使能失败" };
            }

            StaticBean.ToolBean = configModelBean.ToolBean;

            return new MessageBean { IsOk = true, Message = "使能" };
        }

        /// <summary>
        /// 拉铆使能
        /// </summary>
        /// <returns></returns>
        private async Task<MessageBean> RiveteEnable(ConfigModelBean configModelBean, string vinCode, string pointName, Button enableButton, string toolModel)
        {
            try
            {
                Plc toolBean = (Plc)configModelBean.ToolBean;

                StaticBean.ToolBean = toolBean;

                // 发送二维码(VB5100:60byte)
                WriteToPlc(toolBean, vinCode, 60, 5100);

                // 发送钉号(VB2130:20byte)
                WriteToPlc(toolBean, pointName, 20, 2130);

                // 发送使能信号
                toolBean.Write("DB1.DBX5000.0", true);

                enableButton.Invoke(new Action(() => enableButton.BackColor = Color.Green));

                // 调用后台线程监控使能是否结束，结束就做上标记
                _ = Task.Run(async () =>
                {
                    while (true)
                    {
                        // 查询当前状态
                        bool status = (bool)toolBean.Read("Q1152.5");

                        if (status)
                        {
                            await Task.Delay(2000);

                            // 使能断开
                            toolBean.Write("DB1.DBX5000.0", false);

                            toolBean.Write("DB1.DBX5000.1", true);

                            await Task.Delay(1000);

                            toolBean.Write("DB1.DBX5000.1", false);

                            enableButton.Invoke(new Action(() => enableButton.BackColor = Color.White));

                            enableDao.ToolEnable(configModelBean.ToolName, "0");

                            byte result = (byte)toolBean.Read("DB1.DBB106");

                            // 获取状态插入数据
                            enableDao.SaveRepairData(new RepairData()
                            {
                                CreateTime = DateTime.Now,
                                PointName = pointName,
                                ToolModel = toolModel,
                                ToolName = configModelBean.ToolName,
                                VinCode = vinCode,
                                Result = result == 1 ? "OK" : "NG"
                            });

                            break;
                        }

                        await Task.Delay(500);
                    }
                });

                return new MessageBean()
                {
                    IsOk = true,
                    Message = "使能成功"
                };
            }
            catch (Exception e)
            {
                enableButton.Invoke(new Action(() => enableButton.BackColor = Color.White));

                enableDao.ToolEnable(configModelBean.ToolName, "0");

                return new MessageBean()
                {
                    IsOk = false,
                    Message = e.Message,
                };
            }
        }

        /// <summary>
        /// 写入VB区私有方法
        /// </summary>
        /// <param name="plc"></param>
        /// <param name="str"></param>
        /// <param name="index"></param>
        /// <param name="db"></param>
        private void WriteToPlc(Plc plc, string str, int index, int db)
        {
            byte[] bytes = Encoding.ASCII.GetBytes(str);

            byte[] buffer = new byte[index];

            int length = Math.Min(bytes.Length, index);

            Array.Copy(bytes, buffer, length);

            // 用空格填充剩余部分
            for (int i = length; i < index; i++)
            {
                buffer[i] = 0x20;
            }

            plc.WriteBytes(DataType.DataBlock, 1, db, buffer);
        }

        /// <summary>
        /// 存储拧紧的返修数据
        /// </summary>
        /// <param name="tighteningResult"></param>
        /// <param name="pointName"></param>
        /// <param name="vinCode"></param>
        /// <param name="toolName"></param>
        /// <param name="toolModel"></param>
        public void SaveTightenData(TighteningResult tighteningResult, string pointName, string vinCode, string toolName, string toolModel)
        {
            DateTime now = DateTime.Now;

            string result = tighteningResult.IsOK ? "OK" : "NG";

            // 存储拧紧数据
            enableDao.SaveTightenData(new TraceTighten()
            {
                TraceId = vinCode,
                Station = "返修区",
                RangeNo = pointName,
                Torque = tighteningResult.Torque.ToString(),
                Angle = tighteningResult.Angle.ToString(),
                Result = result
            });

            // 存储返修记录
            enableDao.SaveRepairData(new RepairData()
            {
                ToolModel = toolModel,
                VinCode = vinCode,
                ToolName = toolName,
                PointName = pointName,
                Result = result,
                CreateTime = now,
            });
        }

        /// <summary>
        /// 查询返修数据
        /// </summary>
        /// <param name="vinCode"></param>
        /// <returns></returns>
        public List<RepairData> QueryRepairData(string vinCode)
        {
            return enableDao.QueryRepairData(vinCode);
        }

        /// <summary>
        /// 查询相关工具使能状态,返回未使能的工具
        /// </summary>
        /// <param name="toolNameNow"></param>
        /// <returns></returns>
        public string ToolAllIsEnable(string toolNameNow)
        {
            List<RepairToolStatus> repairToolStatuses = enableDao.ToolAllIsEnable(toolNameNow);

            if (repairToolStatuses.Count > 0)
            {
                RepairToolStatus? repairToolStatus = repairToolStatuses.Where(x => x.Status == "0").FirstOrDefault();

                if (repairToolStatus != null)
                {
                    return repairToolStatus.ToolName;
                }
                else
                {
                    return repairToolStatuses[0].ToolName;
                }
            }

            return repairToolStatuses[0].ToolName;
        }
        #endregion

        #region 私有方法

        #endregion
    }
}
